﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Media.Media3D;

using EQEmu.Database;

namespace EQEmu.Grids
{
    public class GridEntriesChangedEventArgs : EventArgs
    {
        public GridEntriesChangedEventArgs(IEnumerable<grid_entries> newitems,IEnumerable<grid_entries> olditems)
        {
            Added = newitems;
            Removed = olditems;
        }

        public IEnumerable<grid_entries> Added { get; private set; }
        public IEnumerable<grid_entries> Removed { get; private set; }
    }

    public class Grid : INotifyPropertyChanged
    {
        private grid _grid;
        protected ObservableCollection<grid_entries> _entries = new ObservableCollection<grid_entries>();

        public event EventHandler<GridEntriesChangedEventArgs> GridEntriesChanged;

        public Grid(grid grid)
        {
            _grid = grid;
            _entries.CollectionChanged += _entries_CollectionChanged;
        }

        void _entries_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            var newitems = e.NewItems != null ? e.NewItems.Cast<grid_entries>() : null;
            var remitems = e.OldItems != null ? e.OldItems.Cast<grid_entries>() : null;
            OnGridEntriesChanged(newitems, remitems);
        }

        private void OnGridEntriesChanged(IEnumerable<grid_entries> added, IEnumerable<grid_entries> removed)
        {
            var e = GridEntriesChanged;
            if (e != null)
            {
                e(this, new GridEntriesChangedEventArgs(added, removed));
            }
        }

        public virtual void AddEntry(grid_entries entry)
        {
            _entries.Add(entry);
        }

        public virtual void RemoveEntry(grid_entries entry)
        {
            _entries.Remove(entry);
        }

        public virtual grid_entries CreateEntry()
        {
            var entry = new grid_entries();
            entry.zoneid = _grid.zoneid;
            entry.gridid = _grid.id;
            entry.number = _entries.Count() == 0 ? 0 : _entries.Max(x => x.number) + 1;
            return entry;
        }

        public grid_entries NearbyWaypoint(Point3D point,double tolerance=2.0)
        {
            foreach (var wp in _entries)
            {
                if (Common.Functions.Distance(point, new Point3D(wp.x, wp.y, wp.z)) <= 2.0)
                {
                    return wp;
                }
            }
            return null;
        }

        public grid GridValue
        {
            get { return _grid; }
            private set
            {
                _grid = value;
            }
        }

        public IEnumerable<grid_entries> Entries
        {
            get { return _entries; }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string info)
        {
            var e = PropertyChanged;
            if (e != null)
            {
                e(this, new PropertyChangedEventArgs(info));
            }
        }

        public override string ToString()
        {
            return "Grid:" + this.GridValue.id;
        }
    }
}
